package com.gec.system.aspect;


import com.alibaba.fastjson.JSON;
import com.gec.model.entity.SysLog;
import com.gec.system.annotation.MyLog;
import com.gec.system.controller.SysLogController;
import com.gec.system.service.SysLogService;
import com.gec.system.util.IpUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;


@Aspect
@Component
public class SysLogAspect {

    @Autowired
    private SysLogController sysLogController;


    //    slf 的LoggerFactory 获得日志API的对象(输入什么Class对象)，用于打印
    private static final Logger log = LoggerFactory.getLogger(SysLogAspect.class);

    /*** 如果处理请求时出现异常，在抛出异常后执行此处代码*
     *   @param joinPoint 切点
     *   @param controllerLog 注解
     *  @param jsonResult 返回值
     *  */
    //    这里通知类型-后置增强   切点设置为打上了注解对象
    //    注意通知的参数和方法的参数保持一致，先有方法的参数，后有通知的参数，注解只是编译时动态处理(生成代码)
    @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")
    public void doAfterReturning(JoinPoint joinPoint, MyLog controllerLog, Object jsonResult) {
        handleLog(joinPoint, controllerLog, null, jsonResult);
    }

    /*** 如果处理请求时出现异常，在抛出异常后执行此处代码
     * @param joinPoint 切点
     * @param e 异常
     * */
    //    这里通知类型-异常增强
    @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, MyLog controllerLog, Exception e) {

        System.out.println("这里有异常");
        handleLog(joinPoint, controllerLog, e, null);
//        e.printStackTrace();
        System.out.println("异常结束");

    }

    /*** 日志处理*/
    protected void handleLog(final JoinPoint joinPoint, MyLog controllerLog, final Exception e, Object jsonResult) {
        try {
            SysLog sysLog = new SysLog();
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            System.out.println("url="+request.getRequestURI());//url=/admin/system/hello
            System.out.println("request.getMethod()"+request.getMethod());//GET
            System.out.println("request.getRemoteAddr()"+request.getRemoteAddr());
//            Object[] args = joinPoint.getArgs();
//            for (Object arg : args) {
//                if (arg instanceof HttpServletRequest) {
//                    HttpServletRequest request1 = (HttpServletRequest) arg;
//                    // 获取请求者IP地址
//                    String ipAddress = request1.getRemoteAddr();
//                    // 记录日志
//                    System.out.println("Request from IP Address: " + ipAddress);
//                }
//            }
            System.out.println("e==null"+e==null);
            System.out.println("getIpAddress"+IpUtil.getIpAddress(request));
//            System.out.println("getGatwayIpAddress"+IpUtil.getGatwayIpAddress((ServerHttpRequest) request));
            System.out.println("joinPoint.toString(): "+joinPoint.toString()); // execution(String com.gec.system.controller.AhelloController.hello())
            System.out.println("joinPoint.toLongString(): "+joinPoint.toLongString());//execution(public java.lang.String com.gec.system.controller.AhelloController.hello())
            System.out.println("joinPoint.toShortString(): "+joinPoint.toShortString());//execution(AhelloController.hello())
            System.out.println("controllerLog.title: "+controllerLog.title());//方法名：你好
            System.out.println("controllerLog.businessType: "+controllerLog.businessType());//INSERT
            System.out.println("jsonResult: "+jsonResult);//返回结果 hello
            System.out.println("title: "+controllerLog.title());
            System.out.println("joinPoint.getArgs()"+joinPoint.getArgs());
            System.out.println("joinPoint.getKind()"+joinPoint.getKind());
            System.out.println(joinPoint.getSignature().getName());
            System.out.println("joinPoint.getSignature()"+joinPoint.getSignature());//String com.gec.system.controller.AhelloController.hello()
            System.out.println("joinPoint.getSourceLocation()"+joinPoint.getSourceLocation());
            System.out.println("joinPoint.getTarget()"+joinPoint.getTarget());//com.gec.system.controller.AhelloController@225cdff3
            System.out.println("joinPoint.getThis()"+joinPoint.getThis());//com.gec.system.controller.AhelloController@225cdff3
//            log.debug("我是log.debug:","message...");    //控制台无法显示
//            log.trace("我是log.trace:","message...");   //控制台无法显示
//            log.error("我是log.error:","message...");    //可打印
//            log.info("我是log.info:","message...");       //可打印
//            log.warn("我是log.warn:","message...");       //可打印

            sysLog.setTitle(controllerLog.title());
            sysLog.setBusinessType(controllerLog.businessType().getType());
            sysLog.setMethod(controllerLog.methodName());
            sysLog.setRequestMethod(request.getMethod());
            sysLog.setOperUrl(request.getRequestURI());
            sysLog.setJsonResult(JSON.toJSONString(jsonResult));
            if (e != null){
                sysLog.setStatus(1);
                sysLog.setErrorMsg(e.getMessage());
            }
            sysLogController.addLog(sysLog);

        } catch (Exception exp) {
            // 记录本地异常日志log.error("**** 出现异常 ****");
            log.error("异常信息:{}", exp.getMessage());
            exp.printStackTrace();
        }
    }

}
